﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NumericalData.Interpolation.Data;

namespace NumericalData.Interpolation.Data
{
    public class DeltasContainer
    {
        private PointsGrid _grid;
        private int _offset;
        private Dictionary<SearchPair,double> _deltas;//point index, order, value

        public DeltasContainer(PointsGrid grid, int centerIndex)
        {
            _grid = grid;
            _offset = centerIndex - 1;
            _deltas = new Dictionary<SearchPair, double>();
        }

        public double GetDelta(int pointIndex, int order)
        {
            var pair = new SearchPair{Index = pointIndex, Order = order};
            double answer;
            if (!_deltas.TryGetValue(pair, out answer))
                return CalculateDelta(pair);
            return answer;
        }

        private double CalculateDelta(SearchPair pair)
        {
            var pointIndex = pair.Index;
            var order = pair.Order;
            if (order == 0)
            {
                var leftIndex = _offset + pointIndex + 1;
                var rightIndex = _offset + pointIndex;
                var value =
                    _grid.Values[leftIndex].Y - _grid.Values[rightIndex].Y;
                 Save(pointIndex,0,value);
                return value;
            }
            else
            {
                var left = GetDelta(pointIndex + 1, order - 1);
                var right = GetDelta(pointIndex, order - 1);
                var value = left - right;
                Save(pointIndex,order,value);
                return value;
            }
        }

        private void Save(int index, int order, double value)
        {
            var pair = new SearchPair{Index = index, Order = order};
            _deltas[pair] = value;
        }

        private class SearchPair
        {
            public int Index { get; set; }
            public int Order { get; set; }

            public override bool Equals(object obj)
            {
                var pair = obj as SearchPair;
                if (pair == null)
                    return false;
                return pair.Index == Index && pair.Order == Order;
            }
            public override int GetHashCode()
            {
                return Math.Abs(Index*10) + Math.Abs(Order);
            }
        }
    
    }

    
}
